package com.study.springbootsecurity.service.impl;

import com.study.springbootsecurity.config.properties.JwtConfigProperties;
import com.study.springbootsecurity.domain.dto.QRCodeDTO;
import com.study.springbootsecurity.entity.LoginUser;
import com.study.springbootsecurity.entity.business.RefreshResponse;
import com.study.springbootsecurity.enums.QrCodeStatuesChangeEventType;
import com.study.springbootsecurity.enums.QrCodeStatus;
import com.study.springbootsecurity.util.CookieUtil;
import com.study.springbootsecurity.util.DeviceFinerUtil;
import com.study.springbootsecurity.util.RedisCache;
import com.study.springbootsecurity.util.TokenUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseCookie;
import org.springframework.messaging.Message;
import org.springframework.statemachine.StateContext;
import org.springframework.statemachine.annotation.OnTransition;
import org.springframework.statemachine.annotation.WithStateMachine;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * @Description: TODO 验证码状态机监听类业务接口
 * @author: Huangjianyun
 * @date: 2025-06-22 0:21
 */
@Component("qrCodeStateListenerImpl")
@WithStateMachine(name = "qrcodeStateMachine")
@Slf4j
public class QrCodeStateListenerImpl {
    private static final String QR_CODE_REDIS_KEY_PREFIX = "qrcode:uuid:";

    @Autowired
    private RedisCache redisCache;

    @Autowired
    TokenService tokenService;

    @Autowired
    JwtConfigProperties jwtConfigProperties;


    @OnTransition(source="WAITING_SCAN",target = "SCANNED_WAITING_CONFIRM")
    public void scannerTransition(Message<QrCodeStatuesChangeEventType> message) {
        // 获取二维码状态数据
        QRCodeDTO qrCodeDTO = (QRCodeDTO) message.getHeaders().get("qrCodeDTO");
        String key = QR_CODE_REDIS_KEY_PREFIX + qrCodeDTO.getUuid();

        // 更新redis数据 必须在二维码扫码事件状态机执行成功才进行更新
        qrCodeDTO.setStatus(QrCodeStatus.SCANNED_WAITING_CONFIRM);
        long ttl = redisCache.getTTL(key);
        redisCache.set(key,qrCodeDTO,ttl, TimeUnit.SECONDS);
    }
    // 二维码创建未扫码状态变更过期状态 触发过期事件
    @OnTransition(source="WAITING_SCAN",target = "EXPIRED_EVENT")
    public void scannerExpiredTransition(Message<QrCodeStatuesChangeEventType> message) {
        // 获取二维码状态数据
        QRCodeDTO qrCodeDTO = (QRCodeDTO) message.getHeaders().get("qrCodeDTO");
        String key = QR_CODE_REDIS_KEY_PREFIX + qrCodeDTO.getUuid();

        // 更新redis数据 必须在二维码扫码事件状态机执行成功才进行更新
        qrCodeDTO.setStatus(QrCodeStatus.EXPIRED);
        long ttl = redisCache.getTTL(key);
        redisCache.set(key,qrCodeDTO,ttl, TimeUnit.SECONDS);
    }

    // 二维码扫码后未认证状态变更确认登录; 触发确认登录事件
    @OnTransition(source="SCANNED_WAITING_CONFIRM",target = "CONFIRMED")
    public void scannerUserConfirmTransition(Message<QrCodeStatuesChangeEventType> message) {
        // 获取二维码状态数据
        QRCodeDTO qrCodeDTO = (QRCodeDTO) message.getHeaders().get("qrCodeDTO");
        String key = QR_CODE_REDIS_KEY_PREFIX + qrCodeDTO.getUuid();
        String username = qrCodeDTO.getScannedUsername();
        // 更新redis数据 必须在二维码扫码事件状态机执行成功才进行更新
        qrCodeDTO.setStatus(QrCodeStatus.CONFIRMED);
        long ttl = redisCache.getTTL(key);
        redisCache.set(key,qrCodeDTO,ttl, TimeUnit.SECONDS);
        // TODO jwt 生成刷新令牌和token 刷新令牌存储redis 并一起返回前端
        // 手机端携带手机端用户名数据
        //登录成功 生成访问令牌和令牌存储并存储刷新令牌到redis
    }


    // 二维码扫码后未认证状态变更取消授权; 触发取消授权登录事件
    @OnTransition(source="SCANNED_WAITING_CONFIRM",target = "CANCELED")
    public void scannerUserCancelTransition(Message<QrCodeStatuesChangeEventType> message) {
        // 获取二维码状态数据
        QRCodeDTO qrCodeDTO = (QRCodeDTO) message.getHeaders().get("qrCodeDTO");
        String key = QR_CODE_REDIS_KEY_PREFIX + qrCodeDTO.getUuid();

        // 更新redis数据 必须在二维码扫码事件状态机执行成功才进行更新
        qrCodeDTO.setStatus(QrCodeStatus.CANCELED);
        long ttl = redisCache.getTTL(key);
        redisCache.set(key,qrCodeDTO,ttl, TimeUnit.SECONDS);
        // TODO 关闭资源 比如临时token等，这里没有生成临时token，不做

    }
}
